Skip to content

Add standalone activity to throughput stress (opt-in)#351

Open
prathyushpv wants to merge 8 commits into
mainfrom
ppv/SA
Open

Add standalone activity to throughput stress (opt-in)#351
prathyushpv wants to merge 8 commits into
mainfrom
ppv/SA

Conversation

@prathyushpv
Copy link
Copy Markdown
Contributor

What was changed

  • Adds a DoStandaloneActivity ClientAction to the kitchen-sink DSL that invokes the payload activity directly via the low-level StartActivityExecution / PollActivityExecution RPCs, bypassing normal workflow activity scheduling.
  • Wires it into throughput_stress behind a new --option enable-standalone-activity=true flag (default off).
  • Threads Namespace through ClientActionsExecutor (required for the namespace-scoped RPCs).
  • Go SDK implements the variant; other SDKs (Java, Python, TS, .NET, Ruby) raise a non-retryable ApplicationFailure if the variant is encountered.

Why?

Mirrors the standalone activity pattern in bench-go's throughputstress scenario so we can benchmark workflow-independent activities (StartActivityExecution / PollActivityExecution) in omes.

Adds a DoStandaloneActivity ClientAction that invokes the payload activity
directly via the low-level StartActivityExecution / PollActivityExecution
RPCs, bypassing normal workflow activity scheduling. Mirrors the standalone
activity pattern in bench-go's throughputstress scenario.

Gated behind --option enable-standalone-activity=true since the API requires
server-side support for workflow-independent activities. Only implemented in
the Go SDK; other SDKs raise a non-retryable ApplicationFailure if the
variant is encountered.
@prathyushpv prathyushpv requested review from a team as code owners May 12, 2026 19:17
Replace the flat bytes_to_receive/bytes_to_return shape with an embedded
ExecuteActivityAction so the standalone-RPC path receives the same
activity input contract as the workflow-scheduled path. The executor
honors activity_type, task_queue, all four timeouts, and retry_policy
from the embedded action; workflow-only fields (awaitable_choice,
locality, priority, fairness_*) are ignored.

Helper StandaloneActivityClientAction is replaced by a StandaloneActivity
factory mirroring DefaultRemoteActivity, so the same ExecuteActivityAction
builders target either path.
DoStandaloneActivity now embeds an ExecuteActivityAction instead of
duplicating payload-activity fields, so the standalone-RPC path and the
workflow-scheduled path receive the same activity input contract and
share dispatch via ActivityNameAndArgs. The executor honors activity_type,
task_queue, all four timeouts, and retry_policy from the embedded action;
workflow-only fields (awaitable_choice, locality, priority, fairness_*)
are ignored.

Scenario invocation switches to payload(256, 256) with a 100ms / x1
RetryPolicy to match bench-go's standalone-activity prebuilt request
shape. Result is decoded for the payload activity to catch encoding
drift between the two scheduling layers.
Migrate executeStandaloneActivity from the raw StartActivityExecution /
PollActivityExecution gRPC stubs to client.ExecuteActivity + handle.Get,
which is available in Go SDK v1.43.0. This drops manual payload encoding,
result decoding, failure parsing, and the Namespace plumbing through
ClientActionsExecutor; namespace is picked up from the SDK client.

Move ConvertFromPBRetryPolicy to loadgen/kitchensink so both the
workflow path (launchActivity) and the standalone path can share it.
Extract createStandaloneActivity into a tpsExecutor method to match the
pattern used by other throughput_stress action constructors.
…ivity

Drop the fallback to e.WorkflowOptions.TaskQueue in
ClientActionsExecutor.executeStandaloneActivity and the conditional 30s
StartToCloseTimeout default in the StandaloneActivity helper — callers
must now set both on the activity directly.

Inline the (now-trivial) StandaloneActivity helper into
throughput_stress.createStandaloneActivity to match how createSelfDescribe,
createSelfQuery, etc. construct their ClientAction protos.
Copy link
Copy Markdown
Contributor

@THardy98 THardy98 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally - would prefer if we kept parity between languages for the operations they support in kitchensink, especially since the code snippet to implement is quite small:

func (e *ClientActionsExecutor) executeStandaloneActivity(ctx context.Context, sa *DoStandaloneActivity) error {
	act := sa.GetActivity()
	if act == nil {
		return fmt.Errorf("DoStandaloneActivity.activity is required")
	}

	actType, args := ActivityNameAndArgs(act)

	handle, err := e.Client.ExecuteActivity(ctx, client.StartActivityOptions{
		ID:                     fmt.Sprintf("standalone-%s-%d", e.WorkflowOptions.ID, time.Now().UnixNano()),
		TaskQueue:              act.TaskQueue,
		ScheduleToCloseTimeout: act.ScheduleToCloseTimeout.AsDuration(),
		ScheduleToStartTimeout: act.ScheduleToStartTimeout.AsDuration(),
		StartToCloseTimeout:    act.StartToCloseTimeout.AsDuration(),
		HeartbeatTimeout:       act.HeartbeatTimeout.AsDuration(),
		RetryPolicy:            ConvertFromPBRetryPolicy(act.RetryPolicy),
	}, actType, args...)
	if err != nil {
		return fmt.Errorf("failed to start standalone activity: %w", err)
	}
	return handle.Get(ctx, nil)
}

across the languages.

If it's pressing to get this in asap, filing an issue would be great so we can track where parity is missing

"do_standalone_activity is not implemented for .NET",
"UnsupportedOperation",
nonRetryable: true);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a flag that exists called err-if-unimplemented or something like that. This is probably a place where we want to check if that's set. If it's false, then we should probably just log instead of throw.

(applies to the other langs where we haven't implemented this as well)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants